package cn.tedu.submarine_2;

import javax.swing.JPanel;
import javax.swing.JFrame;
import java.awt.Graphics;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class World extends JPanel {
    public static final int HEIGHT = 479;
    public static final int WIDTH = 641;
    //运行状态
    public static final int RUNNING=0;
    //暂停状态
    public static final int PAUSE = 1;
    //游戏结束状态
    public static final int GAME_OVER=2;
    //当前状态，默认运行状态
    private int state=RUNNING;
    //窗口中的对象
    private Battleship ship = new Battleship(); //战舰对象
    private SeaObject[] submarines = {}; //潜艇数组
    private Mine[] mines = {}; //水雷数组
    private Bomb[] bombs = {}; //炸弹数组
    //生成潜艇
    private  SeaObject nextSubmarine(){
        Random rand=new Random();
        int type=rand.nextInt(20);
        if(type<10){
            return new ObserveSubmarine();
        }else if (type<16){
            return new TorpedoSubmarine();
        }else {
            return new MineSubmarine();
        }
    }
    private int subEnterIndex = 0; //潜艇入场计数
    /** 潜艇(侦察潜艇、鱼雷潜艇、水雷入场)入场 */
    private void submarineEnterAction(){ //每10毫秒走一次
        subEnterIndex++; //每10毫秒增1
        if(subEnterIndex%40==0){ //每400(40*10)毫秒走一次
            SeaObject obj = nextSubmarine(); //获取潜艇对象
            submarines = Arrays.copyOf(submarines,submarines.length+1); //扩容
            submarines[submarines.length-1] = obj; //将obj添加到submarines的最后一个元素上
        }
    }
    private int mineEnterIndex=0;//水雷进场计数
    private void mineEnterAction(){//每10毫秒走一次
        mineEnterIndex++;
        if(mineEnterIndex%100==0){
            for (int i = 0; i < submarines.length; i++) {//遍历所有的潜艇
                if (submarines[i] instanceof MineSubmarine){
                    MineSubmarine ms=(MineSubmarine) submarines[i];
                    Mine obj=ms.shootMine();
                    mines= Arrays.copyOf(mines,mines.length+1);
                    mines[mines.length-1]=obj;
                }
            }
        }
    }

    /**
     * 海洋对象移动
     */
    private void moveAction(){
        for (int i = 0; i < submarines.length; i++) {
            submarines[i].move();
        }
        for (int j = 0; j <mines.length ; j++) {
            mines[j].move();
        }
        for (int i = 0; i <bombs.length ; i++) {
            bombs[i].move();
        }
    }
    /**
     * 越界对象删除
     */
    private void outOfBoundsAction(){
        //遍历所有潜艇
        for (int i = 0; i <submarines.length ; i++) {
            if (submarines[i].isOutOfBounds()||submarines[i].isDead()){//出界或者死了的
                submarines[i]=submarines[submarines.length-1];//将越界元素替换成最后一个元素
                submarines=Arrays.copyOf(submarines,submarines.length-1);//缩容
            }
        }
        //遍历所有水雷
        for (int i = 0; i <mines.length ; i++) {
            if (mines[i].isOutOfBounds()||mines[i].isDead()){//出界或者死了的
                mines[i]=mines[mines.length-1];//将越界元素替换成最后一个元素
                mines=Arrays.copyOf(mines,mines.length-1);//缩容
            }
        }
        //遍历所有炸弹
        for (int i = 0; i <bombs.length ; i++) {
            if (bombs[i].isOutOfBounds()||bombs[i].isDead()){//出界或者死了的
                bombs[i]=bombs[bombs.length-1];//将越界元素替换成最后一个元素
                bombs=Arrays.copyOf(bombs,bombs.length-1);//缩容
            }
        }

    }
    private int score=0;//玩家得分
    /**
     * 炸弹与潜艇碰撞
     */
    private void bombBangAction(){
        //遍历炸弹
        for (int i = 0; i <bombs.length ; i++) {
            Bomb b=bombs[i];
            //遍历潜艇
            for (int j = 0; j <submarines.length ; j++) {
                SeaObject s=submarines[j];
                //活着并且碰撞，炸弹，潜艇去死
                if(b.isLive()&&s.isLive()&s.isHit(b)){
                    s.goDead();
                    b.goDead();
                    //若碰撞潜艇为分，玩家得分
                    if(s instanceof EnemyScore){
                        EnemyScore es=(EnemyScore) s;//将碰撞潜艇，强转为得分接口
                        score+=es.getScore();//玩家得分
                    }
                    //若碰撞潜艇为命，玩家得命
                    if(s instanceof EnemyLife){
                        EnemyLife el=(EnemyLife) s;//将碰撞潜艇，强转为得命接口
                        int num=el.getLife();//获取命数
                        ship.addLife(num);//战舰得命
                    }
                }
            }
        }
    }
    /**
     * 水雷与战舰碰撞
     */
    private void mineBangAction(){
        for (int i = 0; i < mines.length; i++) {
            Mine m=mines[i];
            if(m.isLive()&&ship.isLive()&&m.isHit(ship)){
                m.goDead();
                ship.subtractLife();
            }
        }
    }
    /**
     * 检测游戏是否结束
     */
    private void checkGameOverAction(){
        if (ship.getLife()<=0){
            state=GAME_OVER;
        }
    }
    /**
     * 启动程序
     */
    public void action(){
        //键盘侦听器---不要求掌握
        KeyAdapter k = new KeyAdapter() {
            /** 重写keyReleased按键抬起事件 keyPressed()键盘按下事件 */
            public void keyReleased(KeyEvent e) { //当按键抬起时会自动触发---不要求掌握
                if(e.getKeyCode()==KeyEvent.VK_P){ //若抬起的是P键---不要求掌握
                    if(state==RUNNING){ //运行状态时修改为暂停状态
                        state = PAUSE;
                    }else if(state==PAUSE){ //暂停状态时修改为运行状态
                        state = RUNNING;
                    }
                }

                if(state==RUNNING){ //仅在运行状态下执行
                    if(e.getKeyCode()==KeyEvent.VK_SPACE){ //若抬起的是空格键---不要求掌握
                        Bomb obj = ship.shootBomb(); //获取炸弹对象
                        bombs = Arrays.copyOf(bombs,bombs.length+1); //扩容
                        bombs[bombs.length-1] = obj; //将obj添加到最后一个元素上
                    }
                    if(e.getKeyCode()==KeyEvent.VK_LEFT){ //若抬起的是左箭头---不要求掌握
                        ship.moveLeft(); //战舰左移
                    }
                    if(e.getKeyCode()==KeyEvent.VK_RIGHT) { //若抬起的是右箭头---不要求掌握
                        ship.moveRight(); //战舰右移
                    }
                }
            }
        };
        this.addKeyListener(k); //添加侦听---不要求掌握
        Timer timer=new Timer();
        int interval=10;
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                submarineEnterAction();
                mineEnterAction();
                moveAction();
                outOfBoundsAction();
                bombBangAction();
                mineEnterAction();
                checkGameOverAction();
                repaint();
            }
        }, interval, interval);
    }

    /**
     * 重写paint方法
     * @param g
     */
    public void paint(Graphics g){
        Images.sea.paintIcon(null,g,0,0);
        ship.paintImage(g);
        for (int i = 0; i <submarines.length ; i++) {
            submarines[i].paintImage(g);
        }
        for (int i = 0; i < mines.length; i++) {
            mines[i].paintImage(g);
        }
        for (int i = 0; i < bombs.length; i++) {
            bombs[i].paintImage(g);
        }
        g.drawString("SCORE: "+score,200,50); //画分---不要求掌握
        g.drawString("LIFE: "+ship.getLife(),400,50); //画命---不要求掌握

        if(state==GAME_OVER){ //若当前为游戏结束状态
            cn.tedu.submarine.Images.gameover.paintIcon(null,g,0,0); //画海洋图---不要求掌握
        }
    }
    public static void main(String[] args) {
        JFrame frame = new JFrame(); //3.
        World world = new World(); //会创建窗口中的那一堆对象
        world.setFocusable(true);
        frame.add(world);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(WIDTH+16, HEIGHT+39);
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        frame.setVisible(true); //系统自动调用paint()方法
        world.action(); //启动程序的执行
    }

}
